﻿/*
 * 1. 将数据从 table person 中，筛选至 table housingdistributionz
 * 2. 只保留对排序有意义的数据，并且根据规则将原始数据进行整合。 
 * 
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Globalization;

namespace HousingDistribution
{
    class HousingDisProc
    {
        public HousingDisProc()
        {
            InitInvalidTitleNameTable();
        }

        public DataTable Proc(PersonTypeEnum personType, DateTime deadline, ArmmanGradeEnum rank)
        {
            //按照既定规则分房排序
            HousingDisSqlCreator sqlCreator = new HousingDisSqlCreator();
            string housingDisSqlStr = sqlCreator.CreateSql(deadline, personType, rank);

            if (housingDisSqlStr == null)
            {
                return null;
            }

            try
            {
                DataSet ds = DBProc.Instance().ReadData(housingDisSqlStr);

                DataTable result = ds.Tables[0];

                FormatHousingDisResult(ref result, personType);

                FormatDataTable(result, personType);

                return result;
            }
            catch (Exception e)
            {
                System.Windows.Forms.MessageBox.Show(e.Message, "分房处理数据库查询错误");
                return null;
            }
        }

        bool MateIsOurEmployee(MateInfo mate)
        {
            foreach (string s in DataDictionary.Instance().Unit())
            {
                if (mate.unit.Equals(s))
                    return true;
            }

            return false;
        }

        
        //格式化分房结果信息: 生成序号，是否抽签等
        void FormatHousingDisResult(ref DataTable dt, PersonTypeEnum personType)
        {
            //因为从mysql查询的datatable缺少相应列，所以需要增加列，以便和datagridview绑定显示出来。
            dt.Columns.Add(DataDictionary.Instance().DGVNewColName(DGVNewColConsts.No), typeof(int));
            dt.Columns.Add(DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_AREA), typeof(string));
            dt.Columns.Add(DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_TYPE), typeof(string));
            dt.Columns.Add(DataDictionary.Instance().DGVNewColName(DGVNewColConsts.BOTH_EMPLOYEE), typeof(string));
            dt.Columns.Add(DataDictionary.Instance().DGVNewColName(DGVNewColConsts.DRAWING), typeof(string));

            PersonSortInfo last = new PersonSortInfo();
            int lastBothEmployee = 0;
            PersonSortInfo cur;
            int curBothEmployee = 0;

            DateTime curDate = DateTime.Now;

            //抽签序号
            int drawingNo = 1;
            bool changeFlag = false;

            StringBuilder addr = new StringBuilder();
            StringBuilder area = new StringBuilder();
            StringBuilder type = new StringBuilder();

            //当前索引号（指示循环进行的位置）
            for (int iter = 0; iter < dt.Rows.Count; iter++)
            {
                DataRow row = dt.Rows[iter];

                row[DataDictionary.Instance().DGVNewColName(DGVNewColConsts.No)] = iter + 1;

                //数据库中的原始housingInfo内容
                string housingInfoStr = (string) row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_INFO)];
                //通过数据库中的housingInfo内容获取格式化的房屋详细信息
                string housingInfoFormatStr = GetHousingStr(housingInfoStr);

                //有院内住房
                if (housingInfoFormatStr != null)
                {
                    //按每套房分解信息
                    string[] info = housingInfoFormatStr.Split("#".ToCharArray());

                    int allArea = 0;
                    string type1 = null;

                    for (int i = 0; i < info.Length; i++)
                    {
                        if (info.Length > 0)
                        {
                            string[] details = info[i].Split(",".ToCharArray());

                            if (details != null && details.Length == 3)
                            {
                                addr.Append(details[0]);
                                addr.Append(";");

                                allArea = allArea + int.Parse(details[1]);
                                //area.Append(details[1]);
                                //area.Append(";");

                                if (type1 == details[2])
                                {
                                    type.Append("");
                                }
                                else
                                {
                                    type.Append(details[2]);
                                    type.Append(";");
                                }
                                type1 = details[2];
                            }
                        }
                    }

                    row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSE_ADDR)] = addr.Remove(addr.Length - 1, 1);
                    //row[DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_AREA)] = area.Remove(area.Length - 1, 1);
                    row[DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_AREA)] = allArea;
                    row[DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_TYPE)] = type.Remove(type.Length - 1, 1);
                    
                    addr.Clear();
                    area.Clear();
                    type.Clear();
                }
                //无院内住房
                else if (housingInfoFormatStr == null)
                {
                    string curAddr = (string)row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSE_ADDR)];
                    string curArea = (string)row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSE_AREA)];
                    if (curAddr != null && curArea != null)
                    {
                        row[DataDictionary.Instance().DGVNewColName(DGVNewColConsts.HOUSE_AREA)] = curArea;
                    }
                }

                curBothEmployee = (int)row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.BOTH_EMPLOYEE)];

                dt.Rows[iter][DataDictionary.Instance().DGVNewColName(DGVNewColConsts.BOTH_EMPLOYEE)] = curBothEmployee == 1 ? "是" : null;

                cur = GetPersonSortInfo(dt.Rows[iter]);

                //备注显示人员星级，未婚，离异，随军
                int marital = (int)row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.MARITAL)];
                int witharmy = (int)row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.WITHARMY)];
                string evaluation = row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.EVALUATION)].ToString();

                //星级人员备注不降级分房
                if (evaluation != "")
                {
                    row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = evaluation;

                    if (marital == (int)PersonMaritalEnum.Unmarried)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] += "未婚";
                    else if (marital == (int)PersonMaritalEnum.DivorcedWithoutChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] += "离异无子女";
                    else if (marital == (int)PersonMaritalEnum.DivorcedWithChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] += "离异有子女";
                    else if (witharmy == (int)WithArmyStatusEnum.NotWithArmyWithoutChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] += "未随军无子女";
                    else if (witharmy == (int)WithArmyStatusEnum.NotWithArmyWithChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] += "未随军有子女";

                }

                //备注标出婚姻和随军状况，离异的标为单身
                else
                {

                    if (marital == (int)PersonMaritalEnum.Unmarried)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = "未婚" + DataDictionary.Instance().GetLowerGrade(cur.sortGrade);
                    else if (marital == (int)PersonMaritalEnum.DivorcedWithoutChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = "离异无子女" + DataDictionary.Instance().GetLowerGrade(cur.sortGrade);
                    else if (marital == (int)PersonMaritalEnum.DivorcedWithChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = "离异有子女";
                    else if (witharmy == (int)WithArmyStatusEnum.NotWithArmyWithoutChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = "未随军无子女" + DataDictionary.Instance().GetLowerGrade(cur.sortGrade);
                    else if (witharmy == (int)WithArmyStatusEnum.NotWithArmyWithChild)
                        row[DataDictionary.Instance().PersonTableFieldName(PersonColConsts.REMARKS)] = "未随军有子女";
                }

                //cur = GetPersonSortInfo(dt.Rows[iter]);

                DataTableInvalidDateCell2Null.Format(ref row, timeTypeCols);

                //比较两个人是否抽签
                //第一个人无需计算
                if (iter > 0)
                {
                    if (lastBothEmployee == curBothEmployee 
                        && this.weightProc.WeightEqual(personType, last, cur) == true)
                    {
                        dt.Rows[iter - 1][DataDictionary.Instance().DGVNewColName(DGVNewColConsts.DRAWING)] = drawingNo;
                        dt.Rows[iter][DataDictionary.Instance().DGVNewColName(DGVNewColConsts.DRAWING)] = drawingNo;

                        changeFlag = true;
                    }
                    else if (changeFlag)
                    {
                        drawingNo++;
                        changeFlag = false;
                    }
                }

                last = cur;
                lastBothEmployee = curBothEmployee;
            }
        }

        private static string[] timeTypeCols = { DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ADMIN_DUTY_TIME), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK_TIME),
                                                   DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_TITLE_TIME), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.CUR_RANK_BEFORE_TIME),
                                                   DataDictionary.Instance().PersonTableFieldName(PersonColConsts.WORK_TIME), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.SCHOOL_TIME),
                                                   DataDictionary.Instance().PersonTableFieldName(PersonColConsts.SIGNUP_TIME), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.RETIREMENT_TIME) };

        private string GetHousingStr(string housingInfo)
        {
            if (housingInfo == null || housingInfo.Contains("#") == false)
                return null;

            StringBuilder housingStr = new StringBuilder();

            StringBuilder sql = new StringBuilder("select * from housing where ");

            string[] infos = housingInfo.Split("#".ToCharArray());
            
            foreach (string str in infos)
            {
                if (str.Length > 0 && str.Contains("*"))
                {
                    int index = str.IndexOf("*");

                    sql.Append("idhousing ='");
                    sql.Append(str.Substring(0, index));
                    sql.Append("' or ");
                }
            }
            //删除最后一个 " or "
            sql = sql.Remove(sql.Length - 4, 4);

            DataTable dt = DBProc.Instance().ReadData(sql.ToString()).Tables[0];

            for (int i = 0; i < dt.Rows.Count; i++)
            {
                HousingOriginalInfo housing = this.housingParser.Parse(dt.Rows[i]);

                housingStr.Append(housing.housingFullAddr);
                housingStr.Append(",");
                housingStr.Append(housing.housingArea);
                housingStr.Append(",");
                housingStr.Append(housing.housingType);
                housingStr.Append("#");
            }

            return housingStr.ToString();
        }

    #region 格式化DataTable
        private void FormatDataTable(DataTable dt, PersonTypeEnum type)
        {
            string[] invalidTitleName = null;

            if (invalidTitleNameTable.ContainsKey(type))
                invalidTitleName = invalidTitleNameTable[type];

            if (invalidTitleName == null)
                return;

            for (int i = dt.Columns.Count - 1; i >= 0; i--)
            {
                if (invalidTitleName.Contains(dt.Columns[i].ColumnName))
                {
                    dt.Columns.Remove(dt.Columns[i].ColumnName);
                }
            }
        }

        static string[] ArmManInvalidTitle = { DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ID), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TYPE), 
                                                DataDictionary.Instance().PersonTableFieldName(PersonColConsts.SERVICE_LENGTH), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.RETIREMENT_TIME),
                                                DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_ELIGIBLE), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.NAME_INITIAL),
                                                DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_INFO), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.FORMER_HOUSING_ID),
                                                DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.WORK_TIME),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.SIGNUP_TIME),
                                                DataDictionary.Instance().PersonTableFieldName(PersonColConsts.BOTH_EMPLOYEE), DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.CUR_GRADE_BEFORE_TIME)
                                             };
                                        
        static string[] StaffInvaliTitle = { DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ID),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TYPE), 
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK_TIME),
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.SERVICE_LENGTH),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.RETIREMENT_TIME),
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_ELIGIBLE),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.NAME_INITIAL),
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_INFO), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.FORMER_HOUSING_ID),
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.EVALUATION),
                                             DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.WORK_TIME),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.SIGNUP_TIME),
                                             DataDictionary.Instance().PersonTableFieldName(PersonColConsts.BOTH_EMPLOYEE),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.CUR_GRADE_BEFORE_TIME) };

        static string[] WorkerInvalidTitle = { DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ID),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TYPE),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ADMIN_DUTY),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ADMIN_DUTY_TIME),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK_TIME),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_TITLE_TIME), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_ELIGIBLE),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.NAME_INITIAL),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.EVALUATION),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_INFO), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.FORMER_HOUSING_ID),
                                                  DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.WORK_TIME),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.SIGNUP_TIME),
                                                  DataDictionary.Instance().PersonTableFieldName(PersonColConsts.BOTH_EMPLOYEE),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.CUR_GRADE_BEFORE_TIME) };

        static string[] NCOInvalidTitle = { DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ID),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TYPE),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ADMIN_DUTY), DataDictionary.Instance().PersonTableFieldName(PersonColConsts.ADMIN_DUTY_TIME),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.TECH_RANK_TIME),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.SERVICE_LENGTH),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.RETIREMENT_TIME),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.HOUSING_ELIGIBLE),DataDictionary.Instance().PersonTableFieldName(PersonColConsts.NAME_INITIAL),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.EVALUATION),
                                               DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.WORK_TIME),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.SIGNUP_TIME),
                                               DataDictionary.Instance().PersonTableFieldName(PersonColConsts.BOTH_EMPLOYEE),DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.CUR_GRADE_BEFORE_TIME) };

        static Dictionary<PersonTypeEnum, string[]> invalidTitleNameTable = new Dictionary<PersonTypeEnum, string[]>();

        void InitInvalidTitleNameTable()
        {
            if (invalidTitleNameTable.ContainsKey(PersonTypeEnum.ArmMan) == false)
                invalidTitleNameTable.Add(PersonTypeEnum.ArmMan, ArmManInvalidTitle);

            if (invalidTitleNameTable.ContainsKey(PersonTypeEnum.Staff) == false)
                invalidTitleNameTable.Add(PersonTypeEnum.Staff, StaffInvaliTitle);

            if (invalidTitleNameTable.ContainsKey(PersonTypeEnum.Worker) == false)
                invalidTitleNameTable.Add(PersonTypeEnum.Worker, WorkerInvalidTitle);

            if (invalidTitleNameTable.ContainsKey(PersonTypeEnum.NCO) == false)
                invalidTitleNameTable.Add(PersonTypeEnum.NCO, NCOInvalidTitle);
        }
    #endregion

        PersonSortInfo GetPersonSortInfo(DataRow dr)
        {
            PersonSortInfo info;

            info.idperson = 0;
            info.sortGrade = dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.GRADE)].ToString();
            info.sortGradeTime = (DateTime)dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.GRADE_TIME)];
            info.sortGradeWeight = (int)dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.GRADE_WEIGHT)];
            info.sortCurGradeBeforeTime = (DateTime)dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.CUR_GRADE_BEFORE_TIME)];
            info.sortWorkTime = (DateTime)dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.WORK_TIME)];
            info.sortSignupTime = (DateTime)dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.SIGNUP_TIME)];
            info.sortMateName = (string) dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.MATE_NAME)];
            info.sortEvaluationWeight = (int) dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.EVALUATION_WEIGHT)];
            info.sortUnitWeight = (int) dr[DataDictionary.Instance().PersonSortInfoTableFieldName(PersonSortInfoColConsts.UNIT_WEIGHT)];

            return info;
        }

        DateProc dateProc = new DateProc("YY-MM-DD");

        ObjectParser parser = new PersonParserFromMySql();
        HousingOriginalInfoFromMySql housingParser = new HousingOriginalInfoFromMySql();

        HousingDisWeightProc weightProc = new HousingDisWeightProc();
    }
}